---
id: event-bus
title: 22. 事件总线
sidebar_label: 22. 事件总线
---

import useBaseUrl from "@docusaurus/useBaseUrl";

## 22.1 什么是事件总线

事件总线是对发布-订阅模式的一种实现。它是一种集中式事件处理机制，允许不同的组件之间进行彼此通信而又不需要相互依赖，达到一种解耦的目的。

我们来看看事件总线的处理流程：

<img src={useBaseUrl("img/event1.png")} />

## 22.2 `MessageCenter` 消息中心

在 `Furion` 框架中，实现了一种轻量级的事件总线实现机制：`MessageCenter`（消息中心），`MessageCenter` 采用字符串消息机制进行广播， 可以在绝大多数中小型项目中发挥作用，缺点是消息处理是在主线程中完成并且消息不支持分布式存储。

另外，`MessageCenter` 支持单播、多播发布及多订阅。如图所示：

<img src={useBaseUrl("img/event2.png")} />

### 22.2.1 注册 `轻量级事件总线服务`

如果想使用 `MessageCenter` 轻量级事件总线，只需要在 `Startup.cs` 中注册服务即可，如：

```cs {3}
public void ConfigureServices(IServiceCollection services)
{
    services.AddSimpleEventBus();
}
```

### 22.2.2 定义订阅处理程序

`MessageCenter` 是根据 `MesseageId` 消息 Id 来触发对应的处理程序的，所以我们需要定义 `订阅处理程序类`，该类需实现 `ISubscribeHandler` 接口，如：

```cs {1,4-5,11-13}
public class UserChangeSubscribeHandler : ISubscribeHandler
{
    // 定义一条消息
    [SubscribeMessage("create:user")]
    public void CreateUser(string eventId, object payload)
    {
        Console.WriteLine("我是"+eventId);
    }

    // 多条消息共用同一个处理程序
    [SubscribeMessage("delete:user")]
    [SubscribeMessage("remove:user")]
    public void RemoveUser(string eventId, object payload)
    {
        Console.WriteLine("我是"+eventId);
    }
}
```

### 22.2.3 发布消息

定义好订阅处理程序后，我们就可以在程序任何地方进行广播消息，事件总线会自动根据 `消息 Id` 触发对应的处理程序方法：

```cs
MessageCenter.Send("create:user", new User {}); // => 打印：我是create:user

MessageCenter.Send("delete:user", new User {}); // => 打印：我是delete:user
MessageCenter.Send("remove:user", new User {}); // => 打印：我是remove:user
```

### 22.2.4 直接订阅消息

在上面的例子中，我们需要创建 `ISubscribeHandler` 的派生类进行相关配置才能实现订阅处理。

在某些特殊情况下，可能只需要订阅一次即可。所以，在 `Furion` 框架中，为了更简便的订阅消息，也提供了 `MessageCenter.Subscribe<T>` 静态方法，如：

```cs
MessageCenter.Subscribe<User>("create:user", (i,p) => {
    // do something。。。
});
```

## 22.3 `MediatR` 库

`Furion` 框架默认只实现了轻量级的事件总线机制，可能还远远未达到大型项目和高并发数据的处理需求。

这个时候，推荐使用 `MediatR` 这个第三方库进行处理，Github 地址：[https://github.com/jbogard/MediatR](https://github.com/jbogard/MediatR)

`MediatR` 是非常优秀的事件总线库，支持单播、多播、消息通知推送、智能调度等操作，非常小巧。

### 22.3.1 `MediatR` 使用文档

[https://github.com/jbogard/MediatR/wiki](https://github.com/jbogard/MediatR/wiki)

## 22.4 反馈与建议

:::note 与我们交流

给 Furion 提 [Issue](https://gitee.com/dotnetchina/Furion/issues/new?issue)。

:::
